<template>
	<!-- 行内布局：仅在 showPosition 且 useRow 为 true 时启用；默认不影响旧用法 -->
	<template v-if="showPosition && useRow">
		<el-row :gutter="20">
			<el-col :xs="24" :lg="deptCol" class="mb20">
				<el-form-item ref="formItem" :prop="prop" :rules="rules">
					<template #label>
						<WtmLabelTooltip :label="label" :tooltip="tooltip" />
					</template>
					<el-cascader
						v-model="modelValue"
						:options="options"
						:props="cascaderProps"
						:clearable="clearable"
						:filterable="filterable"
						:disabled="disabled"
						:placeholder="placeholder"
						:loading="loading"
						class="width100"
						:aria-label="`${label}选择器`"
						@change="handleDeptChange"
						@clear="handleDeptClear"
						@visible-change="handleVisibleChange"
					/>
				</el-form-item>
			</el-col>
			<el-col :xs="24" :lg="positionCol" class="mb20">
				<el-form-item :prop="positionProp" :rules="positionRules">
					<template #label>
						<WtmLabelTooltip :label="positionLabel" :tooltip="positionTooltip" />
					</template>
					<el-select
						v-model="positionIdModel"
						:disabled="positionDisabled || (!modelValue && !positionId)"
						:placeholder="positionLoading ? '加载中...' : positionPlaceholder"
						:loading="positionLoading"
						clearable
						filterable
						class="width100"
						:aria-label="`${positionLabel}选择器`"
						@change="handlePositionChange"
						@clear="handlePositionClear"
					>
						<el-option v-for="item in positions" :key="item.Value" :value="item.Value" :label="item.Text" />
					</el-select>
				</el-form-item>
			</el-col>
		</el-row>
	</template>

	<!-- 默认纵向布局：与历史使用保持完全一致 -->
	<template v-else>
		<el-form-item ref="formItem" :prop="prop" :rules="rules">
			<template #label>
				<WtmLabelTooltip :label="label" :tooltip="tooltip" />
			</template>
			<el-cascader
				v-model="modelValue"
				:options="options"
				:props="cascaderProps"
				:clearable="clearable"
				:filterable="filterable"
				:disabled="disabled"
				:placeholder="placeholder"
				:loading="loading"
				class="width100"
				:aria-label="`${label}选择器`"
				@change="handleDeptChange"
				@clear="handleDeptClear"
				@visible-change="handleVisibleChange"
			/>
		</el-form-item>

		<!-- 可选：岗位选择 -->
		<el-form-item v-if="showPosition" :prop="positionProp" :rules="positionRules">
			<template #label>
				<WtmLabelTooltip :label="positionLabel" tooltip="关联的岗位" />
			</template>
			<el-select
				v-model="positionIdModel"
				:disabled="positionDisabled || (!modelValue && !positionId)"
				:placeholder="positionLoading ? '加载中...' : positionPlaceholder"
				:loading="positionLoading"
				clearable
				filterable
				class="width100"
				:aria-label="`${positionLabel}选择器`"
				@change="handlePositionChange"
				@clear="handlePositionClear"
			>
				<el-option v-for="item in positions" :key="item.Value" :value="item.Value" :label="item.Text" />
			</el-select>
		</el-form-item>
	</template>
</template>

<script setup lang="ts">
import { computed, onMounted, ref, watch, nextTick } from 'vue';
import other from '/@/utils/other';

// 定义组件名称
defineOptions({
	name: 'WtmDeptSelector',
});

// 定义 Props
interface Props {
	/** 部门v-model绑定值 */
	modelValue?: string | number | null;
	/** 部门数据，如果不传则自动加载 */
	options?: any[];
	/** 部门API接口地址 */
	apiUrl?: string;
	/** 是否可清空 */
	clearable?: boolean;
	/** 是否可搜索 */
	filterable?: boolean;
	/** 是否禁用 */
	disabled?: boolean;
	/** 部门占位符 */
	placeholder?: string;
	/** 部门标签 */
	label?: string;
	/** 部门标签提示文字 */
	tooltip?: string;
	/** 部门表单属性名 */
	prop?: string;
	/** 部门验证规则 */
	rules?: any[];
	/** 是否禁用第一级选项 */
	disableFirstLevel?: boolean;
	/** 是否启用认证 */
	auth?: boolean;
	/** 组织ID，可选 */
	orgId?: string | number;
	/** 是否显示公司，默认为false */
	showCompany?: boolean;

	/** 是否展示岗位选择 */
	showPosition?: boolean;
	/** 是否使用 el-row 并列布局（仅对展示岗位时生效） */
	useRow?: boolean;
	/** 并列布局时部门列宽（lg） */
	deptCol?: number | string;
	/** 并列布局时岗位列宽（lg） */
	positionCol?: number | string;
	/** 岗位 v-model 绑定值 */
	positionId?: string | number | null;
	/** 岗位标签提示文字 */
	positionTooltip?: string;
	/** 岗位占位符 */
	positionPlaceholder?: string;
	/** 岗位标签 */
	positionLabel?: string;
	/** 岗位表单属性名 */
	positionProp?: string;
	/** 岗位验证规则 */
	positionRules?: any[];
	/** 是否禁用岗位选择 */
	positionDisabled?: boolean;
	/** 手动提供岗位数据（提供时将不走接口） */
	positionsOptions?: any[];
	/** 岗位接口地址（基础），自动拼接 groupId 参数 */
	positionsApiUrl?: string;
	/** 是否在部门变化时自动发起岗位接口调用 */
	fetchPositions?: boolean;
	/** 部门变化时是否自动清空已选岗位 */
	clearPositionOnDeptChange?: boolean;
}

const props = withDefaults(defineProps<Props>(), {
	modelValue: null,
	options: undefined,
	apiUrl: '/api/common/GetGroups',
	clearable: true,
	filterable: true,
	disabled: false,
	placeholder: '请选择部门',
	label: '部门',
	tooltip: '关联的部门',
	prop: 'Entity.GroupId',
	rules: () => [{ required: true, message: '部门为必填项', trigger: 'blur' }],
	disableFirstLevel: true,
	auth: true,
	orgId: undefined,
	showCompany: false,

	// 岗位相关默认值
	showPosition: false,
	useRow: false,
	deptCol: 12,
	positionCol: 12,
	positionId: null,
	positionTooltip: '关联的岗位',
	positionPlaceholder: '请选择岗位',
	positionLabel: '岗位',
	positionProp: 'Entity.JobPositionId',
	positionRules: () => [{ required: true, message: '岗位为必填项', trigger: 'blur' }],
	positionDisabled: false,
	positionsOptions: undefined,
	positionsApiUrl: '/api/common/getjobpositions',
	fetchPositions: true,
	clearPositionOnDeptChange: true,
});

// 定义 Emits
const emit = defineEmits<{
	'update:modelValue': [value: string | number | null];
	change: [value: string | number | null];
	clear: [];
	'visible-change': [visible: boolean];
	// 岗位相关 v-model
	'update:positionId': [value: string | number | null];
	positionChange: [value: string | number | null, position?: any];
	// 错误事件
	error: [error: { type: 'dept' | 'position'; message: string; details?: any }];
}>();

// 响应式数据
const loading = ref(false);
const internalOptions = ref<any[]>([]);

// 岗位相关
const positionLoading = ref(false);
const internalPositions = ref<any[]>([]);
const positionApiCallCache = ref<Set<string>>(new Set()); // 缓存已调用的API，避免重复调用

// 计算属性 - 部门
const modelValue = computed({
	get: () => props.modelValue,
	set: (value) => emit('update:modelValue', value),
});

const options = computed(() => props.options || internalOptions.value);

// 级联选择器配置
const cascaderProps = computed(() => ({
	checkStrictly: true,
	emitPath: false,
	label: 'Text',
	value: 'Value',
	children: 'Children',
	disabled: (data: any, node: any) => {
		if (props.disableFirstLevel && node.level === 0) return true;
		return false;
	},
	// 添加焦点管理配置
	teleported: true, // 使用teleport避免DOM结构问题
}));

// 计算属性 - 岗位
const positionIdModel = computed({
	get: () => props.positionId,
	set: (value) => {
		emit('update:positionId', value);
		emit('positionChange', value);
	},
});

const positions = computed(() => props.positionsOptions || internalPositions.value);

// 构建API URL
const buildApiUrl = (baseUrl: string, params: Record<string, any>): string => {
	const queryParams = new URLSearchParams();
	Object.entries(params).forEach(([key, value]) => {
		if (value !== undefined && value !== null && value !== '') {
			queryParams.append(key, String(value));
		}
	});
	const separator = baseUrl.includes('?') ? '&' : '?';
	return `${baseUrl}${separator}${queryParams.toString()}`;
};

// 加载部门
const loadOptions = async () => {
	if (props.options) return;
	try {
		loading.value = true;
		const apiUrl = buildApiUrl(props.apiUrl, { auth: props.auth, orgId: props.orgId });
		internalOptions.value = await other.getSelectList(apiUrl, [], false);
	} catch (error) {
		emit('error', {
			type: 'dept',
			message: '加载部门数据失败',
			details: error,
		});
		internalOptions.value = [];
	} finally {
		loading.value = false;
	}
};

// 加载岗位
const loadPositions = async (groupId: string | number | null | undefined) => {
	if (!props.showPosition) return;
	if (!props.fetchPositions) return;
	if (!groupId) {
		internalPositions.value = [];
		positionApiCallCache.value.clear();
		return;
	}

	const cacheKey = `positions_${groupId}`;
	if (positionApiCallCache.value.has(cacheKey)) {
		return; // 已经调用过了，避免重复
	}

	try {
		positionLoading.value = true;
		positionApiCallCache.value.add(cacheKey);
		const url = buildApiUrl(props.positionsApiUrl, { groupId });

		// 先尝试使用getSelectList
		const positions = await other.getSelectList(url, [], false);

		// 如果getSelectList返回空数组，尝试直接调用API
		if (!Array.isArray(positions) || positions.length === 0) {
			try {
				const response = await fetch(url);
				const rawData = await response.json();

				// 检查返回的数据结构
				if (rawData && Array.isArray(rawData)) {
					internalPositions.value = rawData;
				} else if (rawData && Array.isArray(rawData.Data)) {
					internalPositions.value = rawData.Data;
				} else {
					internalPositions.value = [];
				}
			} catch (directError) {
				internalPositions.value = [];
			}
		} else {
			// 使用getSelectList的结果
			internalPositions.value = positions;
		}
	} catch (error) {
		emit('error', {
			type: 'position',
			message: '加载岗位数据失败',
			details: error,
		});
		internalPositions.value = [];
		positionApiCallCache.value.delete(cacheKey); // 失败时移除缓存，允许重试
	} finally {
		positionLoading.value = false;
	}
};

// 根据岗位ID加载单个岗位信息（用于数据回显）
const loadPositionById = async (positionId: string | number) => {
	if (!props.showPosition) return;
	if (!positionId) return;

	const cacheKey = `position_${positionId}`;
	if (positionApiCallCache.value.has(cacheKey)) {
		return; // 已经调用过了，避免重复
	}

	try {
		positionLoading.value = true;
		positionApiCallCache.value.add(cacheKey);
		const url = buildApiUrl(props.positionsApiUrl, { id: positionId });
		const positionData = await other.getSelectList(url, [], false);
		if (positionData && positionData.length > 0) {
			// 如果当前岗位列表中没有这个岗位，添加进去
			const existingPosition = internalPositions.value.find((p) => p.Value === positionId);
			if (!existingPosition) {
				internalPositions.value = [...internalPositions.value, ...positionData];
			}
		}
	} catch (error) {
		emit('error', {
			type: 'position',
			message: '加载岗位详情失败',
			details: error,
		});
		positionApiCallCache.value.delete(cacheKey); // 失败时移除缓存，允许重试
	} finally {
		positionLoading.value = false;
	}
};

// 事件
const handleDeptChange = (value: string | number | null) => {
	if (props.showPosition && props.clearPositionOnDeptChange) {
		emit('update:positionId', null);
	}

	if (props.showPosition && props.fetchPositions && value) {
		// 部门变化时清除缓存，重新加载岗位
		positionApiCallCache.value.clear();
		loadPositions(value);
	}

	emit('change', value);
};

const handleDeptClear = () => {
	// 清空部门自身的值
	emit('update:modelValue', null);
	emit('change', null);

	// 如果启用了岗位功能，同时清空岗位相关数据
	if (props.showPosition && props.clearPositionOnDeptChange) {
		emit('update:positionId', null);
		emit('positionChange', null);
		internalPositions.value = [];
		positionApiCallCache.value.clear();
	}
	emit('clear');
};

// 岗位变化事件
const handlePositionChange = (value: string | number | null) => {
	emit('update:positionId', value);
	// 找到完整的岗位对象并传递
	const position = internalPositions.value.find((p: any) => p.Value === value);
	console.log('岗位选择器 - 岗位变化:', { value, position, allPositions: internalPositions.value });
	emit('positionChange', value, position);
};

// 岗位清空事件
const handlePositionClear = () => {
	emit('update:positionId', null);
	emit('positionChange', null);
};

// 处理级联选择器可见性变化，解决aria-hidden警告
const handleVisibleChange = (visible: boolean) => {
	if (!visible) {
		// 当下拉框关闭时，确保焦点正确管理
		nextTick(() => {
			// 使用更精确的选择器，避免影响其他级联选择器
			const cascaderRef = document.querySelector(`[aria-label="${props.label}选择器"]`) as HTMLElement;
			if (cascaderRef) {
				// 将焦点转移到级联选择器本身，避免焦点停留在下拉框内的元素上
				cascaderRef.focus();
			}
		});
	}
};

// watchers
watch(
	() => props.modelValue,
	(newGroupId, oldGroupId) => {
		// 当部门ID变化时，自动加载对应的岗位数据
		if (props.showPosition && props.fetchPositions && newGroupId && newGroupId !== oldGroupId) {
			// 清除岗位缓存，重新加载
			positionApiCallCache.value.clear();
			loadPositions(newGroupId);
		}
	},
	{ immediate: false }
);

// 监听部门选择器的内部状态变化
watch(
	() => modelValue.value,
	(newValue, oldValue) => {
		// 当内部部门值变化时，确保岗位数据同步更新
		if (props.showPosition && props.fetchPositions && newValue && newValue !== oldValue) {
			// 延迟执行，确保组件状态稳定
			nextTick(() => {
				loadPositions(newValue);
			});
		}
	},
	{ immediate: false }
);

watch(
	() => props.options,
	(newOptions) => {
		if (newOptions) internalOptions.value = newOptions;
	},
	{ immediate: true }
);

watch(
	() => props.apiUrl,
	() => {
		if (!props.options) loadOptions();
	}
);

watch(
	() => props.orgId,
	() => {
		if (!props.options) loadOptions();
	}
);

watch(
	() => props.auth,
	() => {
		if (!props.options) loadOptions();
	}
);

watch(
	() => props.showCompany,
	() => {
		if (!props.options) loadOptions();
	}
);

// 监听岗位ID变化，确保数据回显
watch(
	() => props.positionId,
	(newPositionId) => {
		if (!newPositionId || !props.showPosition) return;

		// 检查当前岗位列表中是否已有该岗位
		const existingPosition = internalPositions.value.find((p) => p.Value === newPositionId);

		if (!existingPosition) {
			// 如果有部门ID，先尝试加载该部门下的所有岗位
			if (props.modelValue && props.fetchPositions) {
				loadPositions(props.modelValue);
			}
			// 如果没有部门ID或者是禁用状态，尝试直接加载单个岗位信息
			else if (props.positionsApiUrl) {
				loadPositionById(newPositionId);
			}
		}
	}
	// 移除 immediate，避免与 onMounted 重复
);

// 监听岗位数据变化，确保界面正确更新
watch(
	() => internalPositions.value,
	() => {
		// 岗位数据更新时的处理逻辑
	},
	{ deep: true }
);

// 属性验证
const validateProps = () => {
	// 验证岗位相关配置
	if (props.showPosition && !props.positionsApiUrl) {
		// showPosition为true时需要配置positionsApiUrl
	}

	// 验证并列布局配置
	if (props.useRow && props.showPosition) {
		const totalCols = Number(props.deptCol) + Number(props.positionCol);
		if (totalCols > 24) {
			// 部门列宽 + 岗位列宽超过24栅格
		}
	}
};

// 部门预置且需要岗位时，初始化加载岗位
onMounted(() => {
	validateProps();
	loadOptions();

	// 统一在这里处理初始化逻辑，避免重复调用
	if (props.showPosition && props.fetchPositions && props.modelValue) {
		loadPositions(props.modelValue);
	}
	// 如果只有岗位ID没有部门ID，尝试加载岗位详情
	else if (props.showPosition && props.positionId && props.positionsApiUrl) {
		loadPositionById(props.positionId);
	}
});
</script>

<style scoped>
.width100 {
	width: 100%;
}

.mb20 {
	margin-bottom: 20px;
}
</style>
